There are six fundamental constraints on the REST architectural style: client-server, stateless, cache, uniform interface, layered system, and code-on-demand. This document details requirements necessary to support HTTP caching constraints for the REST architectural style.
ETag - more reliable validation in situations where it is inconvenient to store modification dates, where the one-second resolution of HTTP date values is not sufficient, or where the origin server wishes to avoid certain paradoxes that might arise from the use of modification dates. Weak validators have an optional W prefix in the header.
Last-Modified - valid if the entity has not been modified since the Last-Modified value
ETag validators come in two variants: strong and weak. Strong validators are preferred over weak.
Use ETag validators whenever possible, MD5 of content or definition. If this is not possible under any means, then optionally use Weak, and if that is not possible, lastly select Last-Modified validators.
Servers should be strong enough to handle BOTH strong ETag and Last-Modified validators.
Two cases of conditional GET exist:
When used with ETags, GET requests use one of If-Match, If-None-Match, or If-Range headers.
When used with Last-Modified, GET requests use one of If-Modified-Since, If-Unmodified-Since.
If-Match
Return the object only if its entity tag (ETag) is the same as the one specified, otherwise return a 412 (Precondition Failed). Default status is 200 (OK).
If-None-Match
Return the object only if its entity tag (ETag) is different from the one specified, otherwise return a 304 (Not Modified). Default status is 200 (OK).
If-Modified-Since
Return the object only if it has been modified since the specified time, otherwise return a 304 (Not Modified). Default status is 200 (OK).
If-Unmodified-Since
Return the object only if it has not been modified since the specified time, otherwise return a 412 (Precondition Failed). Default status is 200 (OK).
These reduce unnecessary network usage by allowing cached entities to be refreshed without requiring multiple requests or transferring data already held by the client.
The server compares the validator against the entity validator, and if they match the server returns 304 (Not Modified). Otherwise it returns a full response.
The behaviour is identical to Conditional GET except that HEAD returns no body.
If-None-Match
Identical to the above except that the failure condition returns a status of 412 (Precondition Failed).
The cache itself uses Expires, Cache-Control headers to manage expiration. These are internal to the cache software and outside of scope.